import * as THREE from 'three';

/**
 *
 * @param getScene 场景
 * @param {string} modelName 模型名称 匹配包含这个名称的模型
 * @param {number} defaultCount 默认3000 当前模型一共会产生多少个实例 只能比实际的多 不能比实际的少 比实际的少时，会无法渲染
 * @returns
 */
export default function useInstanceModel(
  getScene: () => THREE.Scene,
  modelName: string,
  defaultCount = 3000,
) {
  let instancedMesh: THREE.InstancedMesh | null = null;
  let totalModelCount = 0;
  const scene = getScene();

  const createInstanceModel = (mesh: THREE.Group<THREE.Object3DEventMap>) => {
    const models: THREE.Mesh[] = []; // 存储所有树木模型及其位置
    mesh.children.forEach((child) => {
      if (child.name.includes(modelName)) {
        models.push(child);
      }
    });

    if (models.length > 0) {
      const newTotalTreeCount = totalModelCount + models.length;
      if (!instancedMesh) {
        // 树模型是一个组 被分成两个部分了 所以取第一个树枝
        const isGroupModel = models[0].isGroup;
        const currentModel = isGroupModel ? models[0].children[0] : models[0];

        const geometry = currentModel.geometry.clone();
        const material = currentModel.material.clone();
        instancedMesh = new THREE.InstancedMesh(geometry, material, defaultCount);
        instancedMesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage); // 动态更新矩阵
        instancedMesh.visible = false;
        scene.add(instancedMesh);
      } else {
        instancedMesh.visible = true;
        instancedMesh.count = newTotalTreeCount;
        console.log(newTotalTreeCount, totalModelCount);
        instancedMesh.instanceMatrix.needsUpdate = true;
      }

      // 设置树木的位置、缩放和旋转
      models.forEach((model, index) => {
        const currentModel = isGroupModel(model) ? model.children[0] : model;
        currentModel.updateMatrixWorld(); // 确保所有变换都被应用
        const matrix = new THREE.Matrix4();
        matrix.copy(currentModel.matrixWorld); // 复制世界变换矩阵
        instancedMesh!.setMatrixAt(totalModelCount + index, matrix);
      });

      totalModelCount = newTotalTreeCount;

      removeOriginalModels(models);

      console.log(`已创建${totalModelCount}个实例`, instancedMesh, models);
    }
  };

  function removeOriginalModels(models: THREE.Object3D<THREE.Object3DEventMap>[]) {
    models.forEach((model) => {
      model.parent?.remove(model);
    });
  }

  return {
    createInstanceModel,
  };
}

// 辅助函数：判断是否为 Group
function isGroupModel(object: THREE.Object3D): object is THREE.Group {
  return (object as THREE.Group).isGroup;
}
